package com.wxw.BaseLibrary.db;

import android.app.Activity;
import android.os.Handler;
import android.os.Looper;
import android.util.Log;
import android.widget.Toast;
import com.wxw.BaseLibrary.dialog.WaitingDialog;
import com.wxw.BaseLibrary.infa.AsynEventListener;
import com.wxw.BaseLibrary.infa.IGeneralEventCallback;
import com.wxw.BaseLibrary.infa.IThreadPosterHandler;
import com.wxw.BaseLibrary.tool.Timeout;

import java.util.ArrayList;
import java.util.List;

/**
 *
 * @author david
 * @date 2015-11-04
 */
public class DataUpdateManager<T> implements IGeneralEventCallback, IThreadPosterHandler {
    public static final String TAG = "DUM";
    public static String RequestParamName = "data";
    public static List<DataUpdater> dataUpdaters = new ArrayList<DataUpdater>();
    public static int itemCount = 0;
    private List<UpdateDbObject> for_update = new ArrayList<UpdateDbObject>();
    private WaitingDialog waitingDialog = null;
    private String WebService = "";
    private String WebMethod = "";

    private int waitingTime = 180;
    private String message = "";

    private Activity parent = null;
    private IGeneralEventCallback onUpdateCompletedListener;
    private IGeneralEventCallback onUpdatingListener;
    private IGeneralEventCallback onUpdateStartedListener;
    private IGeneralEventCallback onUpdateTimeoutListener;
    private AsynEventListener<T> asynEventListener;

    private String update_data_nothing_selected = "";
    private String sys_info = "";
    private String update_data_timeout = "";
    private String update_data_completed = "";

    /**
     * Gets the lock for Handler to prevent the request result from confusing.
     */
    private static final Object HANDLER_LOCK = new Object();
    /**
     * Poster of send request result.
     */
    private static Handler sRequestHandler;


    public DataUpdateManager(Activity activity){
        parent = activity;
    }

    public List<UpdateDbObject> getForUpdateItems() {
        return for_update;
    }

    public void setForUpdateItems(List<UpdateDbObject> for_update) {
        this.for_update = for_update;
    }

    public void setOnUpdateCompletedListener(IGeneralEventCallback onUpdateCompletedListener) {
        this.onUpdateCompletedListener = onUpdateCompletedListener;
    }

    public void setOnUpdatingListener(IGeneralEventCallback onUpdatingListener) {
        this.onUpdatingListener = onUpdatingListener;
    }

    public void setOnUpdateStartedListener(IGeneralEventCallback onUpdateStartedListener) {
        this.onUpdateStartedListener = onUpdateStartedListener;
    }

    public void setOnUpdateTimeoutListener(IGeneralEventCallback onUpdateTimeoutListener) {
        this.onUpdateTimeoutListener = onUpdateTimeoutListener;
    }

    public void setAsynEventListener(AsynEventListener<T> asynEventListener) {
        this.asynEventListener = asynEventListener;
    }

    public String getMessage() {
        return message;
    }

    public void setMessage(String message) {
        this.message = message;
    }

    public String getWebService() {
        return WebService;
    }

    public void setWebService(String webService) {
        WebService = webService;
    }

    public String getWebMethod() {
        return WebMethod;
    }

    public void setWebMethod(String webMethod) {
        WebMethod = webMethod;
    }

    public String getUpdate_data_nothing_selected() {
        return update_data_nothing_selected;
    }

    public void setUpdate_data_nothing_selected(String update_data_nothing_selected) {
        this.update_data_nothing_selected = update_data_nothing_selected;
    }

    public int getWaitingTime() {
        return waitingTime;
    }

    public void setWaitingTime(int waitingTime) {
        this.waitingTime = waitingTime;
    }

    public String getSys_info() {
        return sys_info;
    }

    public void setSys_info(String sys_info) {
        this.sys_info = sys_info;
    }

    public String getUpdate_data_timeout() {
        return update_data_timeout;
    }

    public void setUpdate_data_timeout(String update_data_timeout) {
        this.update_data_timeout = update_data_timeout;
    }

    public String getUpdateCompleted() {
        return update_data_completed;
    }

    public void setUpdateCompleted(String update_data_completed) {
        this.update_data_completed = update_data_completed;
    }

    public void cancel() {
        for (DataUpdater dataUpdater : dataUpdaters) {
            dataUpdater.cancel();
        }
    }

    public void start() {
        if (for_update.size() <= 0){
            Toast.makeText(parent, update_data_nothing_selected, Toast.LENGTH_SHORT).show();
            return;
        }
        itemCount = for_update.size();
        if (onUpdateStartedListener != null) {
            onUpdateStartedListener.finished(this, "Started");
        }
        waitingDialog = new WaitingDialog(parent, sys_info, message, waitingTime, new Timeout.OnTimeoutListener() {
            @Override
            public void onTimeout(Object sender, int time) {
                if (onUpdateTimeoutListener != null) {
                    onUpdateTimeoutListener.finished(DataUpdateManager.this, update_data_timeout);
                }
            }
        });
        new Thread(new Runnable() {
            @Override
            public void run() {
//                ThreadPoster<T> poster = new ThreadPoster<T>(0, asynEventListener);
//                poster.onStart();
//                getPosterHandler().post(poster);
                try {
                    for (UpdateDbObject item : for_update){
                        DataUpdater dataUpdater = new DataUpdater(item.type, item.iDbObject, DataUpdateManager.this);
                        dataUpdater.setDataInfo(item.title);
                        dataUpdaters.add(dataUpdater);
                        dataUpdater.setOnUpdatingListener(DataUpdateManager.this);
                        dataUpdater.setOnCompletedListener(new IGeneralEventCallback() {
                            @Override
                            public void finished(Object sender, String eventContent) {
                                try {
                                    itemCount--;
                                    if (onUpdatingListener != null) {
                                        onUpdatingListener.finished(sender, eventContent);
                                    }
                                    if (itemCount <= 0) {
                                        dataUpdaters.clear();
                                        if (waitingDialog!=null) {
                                            waitingDialog.stop();
                                        }
                                        if (onUpdateCompletedListener != null) {
                                            onUpdateCompletedListener.finished(this, update_data_completed);
                                        }
                                        waitingDialog = null;
                                    }
                                } catch (Exception e) {
                                    Log.e(TAG, e.getMessage());
                                }
                            }
                        });
                        dataUpdater.setClearDB(item.iDbObject.doClear());
                        dataUpdater.getBaseDataByPost();
                    }
                } catch (Exception e) {
                    e.printStackTrace();
                    Log.e(TAG, e.getMessage());
                }
            }
        }).start();
    }

    @Override
    public void finished(Object sender, String eventContent) {
        try {
            if (onUpdatingListener != null) {
                onUpdatingListener.finished(sender, eventContent);
            }
        } catch (Exception e) {
            Log.e(TAG, e.getMessage());
        }
    }

    @Override
    public Handler getPosterHandler() {
        synchronized (HANDLER_LOCK) {
            if (sRequestHandler == null) {
                sRequestHandler = new Handler(Looper.getMainLooper());
            }
        }
        return sRequestHandler;
    }

//    public static List<UpdateDbObject> createUpdateItems(){
//        List<UpdateDbObject> items = new ArrayList<UpdateDbObject>();
//        UpdateDbObject updateDbObject = new UpdateDbObject();
//        updateDbObject.iDbObject = new Customer();
//        updateDbObject.type = new TypeToken<List<Customer>>(){}.getType();
//        updateDbObject.title = SystemStatus.MainActivity.getString(R.string.update_data_item1);
//        updateDbObject.checked = true;
//        items.add(updateDbObject);
//        items.add(updateDbObject);
//        return items;
//    }
}
